package org.vacoor.nothing.misc.express.fedex;

import com.fedex.addressvalidation.stub.*;

import java.util.Calendar;

/**
 */
public class FedExAddrValidationService extends FedExSupport {

    public void validate() {
        //
        AddressValidationRequest req = new AddressValidationRequest();

        // 授权, 客户端, 协议版本信息
        req.setWebAuthenticationDetail(new WebAuthenticationDetail(new WebAuthenticationCredential(getKey(), getPassword())));
        req.setClientDetail(new ClientDetail(getAccountNumber(), getMeterNumber(), getIntegratorId(), null));
        req.setTransactionDetail(new TransactionDetail("Address Validation Request", null));
        req.setVersion(new VersionId("aval", 3, 0, 0));

        //
        Calendar c = Calendar.getInstance();
        req.setInEffectAsOfTimestamp(c);
        //
        AddressToValidate av1 = new AddressToValidate();
        Address a1 = new Address();
        a1.setStreetLines(new String[]{"10 FedEx Parkway"});
        a1.setPostalCode("38017");
        av1.setAddress(a1);
        av1.setClientReferenceId("ClientReferenceId1");
        AddressToValidate av2 = new AddressToValidate();
        Address a2 = new Address();
        a2.setStreetLines(new String[]{"50 N Front St"});
        a2.setPostalCode("38103");
        av2.setAddress(a2);
        av2.setClientReferenceId("ClientReferenceId2");

        req.setAddressesToValidate(new AddressToValidate[]{av1, av2});
        //
        try {
            // Initialize the service
            AddressValidationServiceLocator service;
            AddressValidationPortType port;
            //
            service = new AddressValidationServiceLocator();
            // updateEndPoint(service);
            port = service.getAddressValidationServicePort();
            // This is the call to the web service
            AddressValidationReply reply = port.addressValidation(req);
            System.out.println("Transactions successful");
            System.out.println();
            //
            if (isResponseOk(reply.getHighestSeverity())) {
                AddressValidationResult[] avr = reply.getAddressResults();
                for (int i = 0; i < avr.length; i++) {
                    System.out.println("Address Id - " + avr[i].getClientReferenceId());
                    Address address = avr[i].getEffectiveAddress();
                    System.out.println("--- Effective Address--- ");
                    String[] streetlines = address.getStreetLines();
                    for (int j = 0; j < streetlines.length; j++) {
                        System.out.println("  " + streetlines[j]);
                    }
                    if (address.getCity() != null) System.out.println("  " + address.getCity());
                    if (address.getStateOrProvinceCode() != null)
                        System.out.println("  " + address.getStateOrProvinceCode());
                    if (address.getPostalCode() != null) System.out.println("  " + address.getPostalCode());
                    if (address.getCountryCode() != null) System.out.println("  " + address.getCountryCode());
                    System.out.println();
                    System.out.println("--- Address Attributes ---");
                    AddressAttribute[] attributes = avr[i].getAttributes();
                    for (int j = 0; j < attributes.length; j++) {
                        System.out.println("  " + attributes[j].getName() + ": " + attributes[j].getValue());
                    }
                    System.out.println();
                    System.out.println();
                }
            }

            printNotifications(reply.getNotifications());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static boolean isResponseOk(NotificationSeverityType notificationSeverityType) {
        if (notificationSeverityType == null) {
            return false;
        }
        if (notificationSeverityType.equals(NotificationSeverityType.WARNING) ||
                notificationSeverityType.equals(NotificationSeverityType.NOTE) ||
                notificationSeverityType.equals(NotificationSeverityType.SUCCESS)) {
            return true;
        }
        return false;
    }

    private static void printNotifications(Notification[] notifications) {
        System.out.println("Notifications:");
        if (notifications == null || notifications.length == 0) {
            System.out.println("  No notifications returned");
        }
        for (int i = 0; i < notifications.length; i++) {
            Notification n = notifications[i];
            System.out.print("  Notification no. " + i + ": ");
            if (n == null) {
                System.out.println("null");
                continue;
            } else {
                System.out.println("");
            }
            NotificationSeverityType nst = n.getSeverity();

            System.out.println("    Severity: " + (nst == null ? "null" : nst.getValue()));
            System.out.println("    Code: " + n.getCode());
            System.out.println("    Message: " + n.getMessage());
            System.out.println("    Source: " + n.getSource());
        }
    }
}
